// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'package:_fe_analyzer_shared/src/experiments/flags.dart';
import 'package:_fe_analyzer_shared/src/parser/assert.dart';
import 'package:_fe_analyzer_shared/src/parser/block_kind.dart';
import 'package:_fe_analyzer_shared/src/parser/constructor_reference_context.dart';
import 'package:_fe_analyzer_shared/src/parser/declaration_kind.dart';
import 'package:_fe_analyzer_shared/src/parser/formal_parameter_kind.dart';
import 'package:_fe_analyzer_shared/src/parser/identifier_context.dart';
import 'package:_fe_analyzer_shared/src/parser/listener.dart';
import 'package:_fe_analyzer_shared/src/parser/member_kind.dart';
import 'package:_fe_analyzer_shared/src/scanner/error_token.dart';
import 'package:_fe_analyzer_shared/src/scanner/token.dart';
import 'package:front_end/src/base/messages.dart';

// THIS FILE IS AUTO GENERATED BY 'test/parser_test_listener_creator.dart'
// Run this command to update it:
// 'dart pkg/front_end/test/parser_test_listener_creator.dart'

class ParserTestListener implements Listener {
  int indent = 0;
  final StringBuffer sb = new StringBuffer();
  final bool trace;

  ParserTestListener(this.trace);

  String createTrace() {
    List<String> traceLines = StackTrace.current.toString().split("\n");
    for (int i = 0; i < traceLines.length; i++) {
      // Find first one that's not any of the denylisted ones.
      String line = traceLines[i];
      if (line.contains("parser_test_listener.dart:") ||
          line.contains("parser_suite.dart:")) {
        continue;
      }
      return line.substring(line.indexOf("(") + 1, line.lastIndexOf(")"));
    }
    return "N/A";
  }

  void doPrint(String s) {
    String outString = s;
    if (trace) outString += " (${createTrace()})";
    if (outString != "") {
      sb.writeln(("  " * indent) + outString);
    } else {
      sb.writeln("");
    }
  }

  bool checkEof(Token token) {
    if (token.isEof) {
      doPrint("// WARNING: Reporting at eof for $token.");
      return true;
    }
    Token? next = token.next;
    while (next != null && next.offset == token.offset && !next.isEof) {
      next = next.next;
    }
    if (next != null && next.offset == token.offset && next.isEof) {
      doPrint("// WARNING: Reporting at the eof offset for $token.");
      return true;
    }
    return false;
  }

  void seen(Token? token) {}

  @override
  void logEvent(String name) {
    doPrint(
      'logEvent('
      '$name)',
    );
  }

  @override
  void beginArguments(Token token) {
    seen(token);
    doPrint(
      'beginArguments('
      '$token)',
    );
    indent++;
  }

  @override
  void endArguments(int count, Token beginToken, Token endToken) {
    indent--;
    seen(beginToken);
    seen(endToken);
    doPrint(
      'endArguments('
      '$count, '
      '$beginToken, '
      '$endToken)',
    );
  }

  @override
  void handleObjectPatternFields(int count, Token beginToken, Token endToken) {
    seen(beginToken);
    seen(endToken);
    doPrint(
      'handleObjectPatternFields('
      '$count, '
      '$beginToken, '
      '$endToken)',
    );
  }

  @override
  void handleAsyncModifier(Token? asyncToken, Token? starToken) {
    seen(asyncToken);
    seen(starToken);
    doPrint(
      'handleAsyncModifier('
      '$asyncToken, '
      '$starToken)',
    );
  }

  @override
  void beginAwaitExpression(Token token) {
    seen(token);
    doPrint(
      'beginAwaitExpression('
      '$token)',
    );
    indent++;
  }

  @override
  void endAwaitExpression(Token beginToken, Token endToken) {
    indent--;
    seen(beginToken);
    seen(endToken);
    doPrint(
      'endAwaitExpression('
      '$beginToken, '
      '$endToken)',
    );
  }

  @override
  void endInvalidAwaitExpression(
    Token beginToken,
    Token endToken,
    MessageCode errorCode,
  ) {
    indent--;
    seen(beginToken);
    seen(endToken);
    doPrint(
      'endInvalidAwaitExpression('
      '$beginToken, '
      '$endToken, '
      '$errorCode)',
    );
  }

  @override
  void beginBlock(Token token, BlockKind blockKind) {
    seen(token);
    doPrint(
      'beginBlock('
      '$token, '
      '$blockKind)',
    );
    indent++;
  }

  @override
  void endBlock(
    int count,
    Token beginToken,
    Token endToken,
    BlockKind blockKind,
  ) {
    indent--;
    seen(beginToken);
    seen(endToken);
    doPrint(
      'endBlock('
      '$count, '
      '$beginToken, '
      '$endToken, '
      '$blockKind)',
    );
  }

  @override
  void handleInvalidTopLevelBlock(Token token) {
    seen(token);
    doPrint(
      'handleInvalidTopLevelBlock('
      '$token)',
    );
  }

  @override
  void beginCascade(Token token) {
    seen(token);
    doPrint(
      'beginCascade('
      '$token)',
    );
    indent++;
  }

  @override
  void endCascade() {
    indent--;
    doPrint('endCascade()');
  }

  @override
  void beginCaseExpression(Token caseKeyword) {
    seen(caseKeyword);
    doPrint(
      'beginCaseExpression('
      '$caseKeyword)',
    );
    indent++;
  }

  @override
  void endCaseExpression(Token caseKeyword, Token? when, Token colon) {
    indent--;
    seen(caseKeyword);
    seen(when);
    seen(colon);
    doPrint(
      'endCaseExpression('
      '$caseKeyword, '
      '$when, '
      '$colon)',
    );
  }

  @override
  void beginClassOrMixinOrExtensionBody(DeclarationKind kind, Token token) {
    seen(token);
    doPrint(
      'beginClassOrMixinOrExtensionBody('
      '$kind, '
      '$token)',
    );
    indent++;
  }

  @override
  void endClassOrMixinOrExtensionBody(
    DeclarationKind kind,
    int memberCount,
    Token beginToken,
    Token endToken,
  ) {
    indent--;
    seen(beginToken);
    seen(endToken);
    doPrint(
      'endClassOrMixinOrExtensionBody('
      '$kind, '
      '$memberCount, '
      '$beginToken, '
      '$endToken)',
    );
  }

  @override
  void beginClassOrMixinOrNamedMixinApplicationPrelude(Token token) {
    seen(token);
    doPrint(
      'beginClassOrMixinOrNamedMixinApplicationPrelude('
      '$token)',
    );
    indent++;
  }

  @override
  void beginClassDeclaration(
    Token begin,
    Token? abstractToken,
    Token? macroToken,
    Token? sealedToken,
    Token? baseToken,
    Token? interfaceToken,
    Token? finalToken,
    Token? augmentToken,
    Token? mixinToken,
    Token name,
  ) {
    seen(begin);
    seen(abstractToken);
    seen(macroToken);
    seen(sealedToken);
    seen(baseToken);
    seen(interfaceToken);
    seen(finalToken);
    seen(augmentToken);
    seen(mixinToken);
    seen(name);
    doPrint(
      'beginClassDeclaration('
      '$begin, '
      '$abstractToken, '
      '$macroToken, '
      '$sealedToken, '
      '$baseToken, '
      '$interfaceToken, '
      '$finalToken, '
      '$augmentToken, '
      '$mixinToken, '
      '$name)',
    );
    indent++;
  }

  @override
  void handleClassExtends(Token? extendsKeyword, int typeCount) {
    seen(extendsKeyword);
    doPrint(
      'handleClassExtends('
      '$extendsKeyword, '
      '$typeCount)',
    );
  }

  @override
  void handleImplements(Token? implementsKeyword, int interfacesCount) {
    seen(implementsKeyword);
    doPrint(
      'handleImplements('
      '$implementsKeyword, '
      '$interfacesCount)',
    );
  }

  @override
  void handleClassHeader(Token begin, Token classKeyword, Token? nativeToken) {
    seen(begin);
    seen(classKeyword);
    seen(nativeToken);
    doPrint(
      'handleClassHeader('
      '$begin, '
      '$classKeyword, '
      '$nativeToken)',
    );
  }

  @override
  void handleRecoverDeclarationHeader(DeclarationHeaderKind kind) {
    doPrint(
      'handleRecoverDeclarationHeader('
      '$kind)',
    );
  }

  @override
  void endClassDeclaration(Token beginToken, Token endToken) {
    indent--;
    seen(beginToken);
    seen(endToken);
    doPrint(
      'endClassDeclaration('
      '$beginToken, '
      '$endToken)',
    );
  }

  @override
  void handleNoClassBody(Token semicolonToken) {
    seen(semicolonToken);
    doPrint(
      'handleNoClassBody('
      '$semicolonToken)',
    );
  }

  @override
  void handleNoExtensionTypeBody(Token semicolonToken) {
    seen(semicolonToken);
    doPrint(
      'handleNoExtensionTypeBody('
      '$semicolonToken)',
    );
  }

  @override
  void beginMixinDeclaration(
    Token beginToken,
    Token? augmentToken,
    Token? baseToken,
    Token mixinKeyword,
    Token name,
  ) {
    seen(beginToken);
    seen(augmentToken);
    seen(baseToken);
    seen(mixinKeyword);
    seen(name);
    doPrint(
      'beginMixinDeclaration('
      '$beginToken, '
      '$augmentToken, '
      '$baseToken, '
      '$mixinKeyword, '
      '$name)',
    );
    indent++;
  }

  @override
  void handleMixinOn(Token? onKeyword, int typeCount) {
    seen(onKeyword);
    doPrint(
      'handleMixinOn('
      '$onKeyword, '
      '$typeCount)',
    );
  }

  @override
  void handleMixinHeader(Token mixinKeyword) {
    seen(mixinKeyword);
    doPrint(
      'handleMixinHeader('
      '$mixinKeyword)',
    );
  }

  @override
  void handleRecoverMixinHeader() {
    doPrint('handleRecoverMixinHeader()');
  }

  @override
  void endMixinDeclaration(Token beginToken, Token endToken) {
    indent--;
    seen(beginToken);
    seen(endToken);
    doPrint(
      'endMixinDeclaration('
      '$beginToken, '
      '$endToken)',
    );
  }

  @override
  void beginUncategorizedTopLevelDeclaration(Token token) {
    seen(token);
    doPrint(
      'beginUncategorizedTopLevelDeclaration('
      '$token)',
    );
    indent++;
  }

  @override
  void beginExtensionDeclarationPrelude(Token extensionKeyword) {
    seen(extensionKeyword);
    doPrint(
      'beginExtensionDeclarationPrelude('
      '$extensionKeyword)',
    );
    indent++;
  }

  @override
  void beginExtensionDeclaration(
    Token? augmentToken,
    Token extensionKeyword,
    Token? name,
  ) {
    seen(augmentToken);
    seen(extensionKeyword);
    seen(name);
    doPrint(
      'beginExtensionDeclaration('
      '$augmentToken, '
      '$extensionKeyword, '
      '$name)',
    );
    indent++;
  }

  @override
  void endExtensionDeclaration(
    Token beginToken,
    Token extensionKeyword,
    Token? onKeyword,
    Token endToken,
  ) {
    indent--;
    seen(beginToken);
    seen(extensionKeyword);
    seen(onKeyword);
    seen(endToken);
    doPrint(
      'endExtensionDeclaration('
      '$beginToken, '
      '$extensionKeyword, '
      '$onKeyword, '
      '$endToken)',
    );
  }

  @override
  void beginExtensionTypeDeclaration(
    Token? augmentKeyword,
    Token extensionKeyword,
    Token name,
  ) {
    seen(augmentKeyword);
    seen(extensionKeyword);
    seen(name);
    doPrint(
      'beginExtensionTypeDeclaration('
      '$augmentKeyword, '
      '$extensionKeyword, '
      '$name)',
    );
    indent++;
  }

  @override
  void endExtensionTypeDeclaration(
    Token beginToken,
    Token? augmentToken,
    Token extensionKeyword,
    Token typeKeyword,
    Token endToken,
  ) {
    indent--;
    seen(beginToken);
    seen(augmentToken);
    seen(extensionKeyword);
    seen(typeKeyword);
    seen(endToken);
    doPrint(
      'endExtensionTypeDeclaration('
      '$beginToken, '
      '$augmentToken, '
      '$extensionKeyword, '
      '$typeKeyword, '
      '$endToken)',
    );
  }

  @override
  void beginPrimaryConstructor(Token beginToken) {
    seen(beginToken);
    doPrint(
      'beginPrimaryConstructor('
      '$beginToken)',
    );
    indent++;
  }

  @override
  void endPrimaryConstructor(
    Token beginToken,
    Token? constKeyword,
    bool hasConstructorName,
    bool forExtensionType,
  ) {
    indent--;
    seen(beginToken);
    seen(constKeyword);
    doPrint(
      'endPrimaryConstructor('
      '$beginToken, '
      '$constKeyword, '
      '$hasConstructorName, '
      '$forExtensionType)',
    );
  }

  @override
  void handleNoPrimaryConstructor(
    Token token,
    Token? constKeyword,
    bool forExtensionType,
  ) {
    seen(token);
    seen(constKeyword);
    doPrint(
      'handleNoPrimaryConstructor('
      '$token, '
      '$constKeyword, '
      '$forExtensionType)',
    );
  }

  @override
  void beginPrimaryConstructorBody(Token token) {
    seen(token);
    doPrint(
      'beginPrimaryConstructorBody('
      '$token)',
    );
    indent++;
  }

  @override
  void endPrimaryConstructorBody(
    Token beginToken,
    Token? beginInitializers,
    Token endToken,
  ) {
    indent--;
    seen(beginToken);
    seen(beginInitializers);
    seen(endToken);
    doPrint(
      'endPrimaryConstructorBody('
      '$beginToken, '
      '$beginInitializers, '
      '$endToken)',
    );
  }

  @override
  void beginCombinators(Token token) {
    seen(token);
    doPrint(
      'beginCombinators('
      '$token)',
    );
    indent++;
  }

  @override
  void endCombinators(int count) {
    indent--;
    doPrint(
      'endCombinators('
      '$count)',
    );
  }

  @override
  void beginCompilationUnit(Token token) {
    seen(token);
    doPrint(
      'beginCompilationUnit('
      '$token)',
    );
    indent++;
  }

  @override
  void handleDirectivesOnly() {
    doPrint('handleDirectivesOnly()');
  }

  @override
  void endCompilationUnit(int count, Token token) {
    indent--;
    seen(token);
    doPrint(
      'endCompilationUnit('
      '$count, '
      '$token)',
    );
  }

  @override
  void beginConstLiteral(Token token) {
    seen(token);
    doPrint(
      'beginConstLiteral('
      '$token)',
    );
    indent++;
  }

  @override
  void endConstLiteral(Token endToken) {
    indent--;
    seen(endToken);
    doPrint(
      'endConstLiteral('
      '$endToken)',
    );
  }

  @override
  void beginConstructorReference(Token start) {
    seen(start);
    doPrint(
      'beginConstructorReference('
      '$start)',
    );
    indent++;
  }

  @override
  void endConstructorReference(
    Token start,
    Token? periodBeforeName,
    Token endToken,
    ConstructorReferenceContext constructorReferenceContext,
  ) {
    indent--;
    seen(start);
    seen(periodBeforeName);
    seen(endToken);
    doPrint(
      'endConstructorReference('
      '$start, '
      '$periodBeforeName, '
      '$endToken, '
      '$constructorReferenceContext)',
    );
  }

  @override
  void beginDoWhileStatement(Token token) {
    seen(token);
    doPrint(
      'beginDoWhileStatement('
      '$token)',
    );
    indent++;
  }

  @override
  void endDoWhileStatement(
    Token doKeyword,
    Token whileKeyword,
    Token endToken,
  ) {
    indent--;
    seen(doKeyword);
    seen(whileKeyword);
    seen(endToken);
    doPrint(
      'endDoWhileStatement('
      '$doKeyword, '
      '$whileKeyword, '
      '$endToken)',
    );
  }

  @override
  void beginDoWhileStatementBody(Token token) {
    seen(token);
    doPrint(
      'beginDoWhileStatementBody('
      '$token)',
    );
    indent++;
  }

  @override
  void endDoWhileStatementBody(Token token) {
    indent--;
    seen(token);
    doPrint(
      'endDoWhileStatementBody('
      '$token)',
    );
  }

  @override
  void beginWhileStatementBody(Token token) {
    seen(token);
    doPrint(
      'beginWhileStatementBody('
      '$token)',
    );
    indent++;
  }

  @override
  void endWhileStatementBody(Token endToken) {
    indent--;
    seen(endToken);
    doPrint(
      'endWhileStatementBody('
      '$endToken)',
    );
  }

  @override
  void beginEnumDeclarationPrelude(Token enumKeyword) {
    seen(enumKeyword);
    doPrint(
      'beginEnumDeclarationPrelude('
      '$enumKeyword)',
    );
    indent++;
  }

  @override
  void beginEnumDeclaration(
    Token beginToken,
    Token? augmentToken,
    Token enumKeyword,
    Token name,
  ) {
    seen(beginToken);
    seen(augmentToken);
    seen(enumKeyword);
    seen(name);
    doPrint(
      'beginEnumDeclaration('
      '$beginToken, '
      '$augmentToken, '
      '$enumKeyword, '
      '$name)',
    );
    indent++;
  }

  @override
  void endEnumDeclaration(
    Token beginToken,
    Token enumKeyword,
    Token leftBrace,
    int memberCount,
    Token endToken,
  ) {
    indent--;
    seen(beginToken);
    seen(enumKeyword);
    seen(leftBrace);
    seen(endToken);
    doPrint(
      'endEnumDeclaration('
      '$beginToken, '
      '$enumKeyword, '
      '$leftBrace, '
      '$memberCount, '
      '$endToken)',
    );
  }

  @override
  void handleEnumElements(Token elementsEndToken, int elementsCount) {
    seen(elementsEndToken);
    doPrint(
      'handleEnumElements('
      '$elementsEndToken, '
      '$elementsCount)',
    );
  }

  @override
  void handleEnumHeader(
    Token? augmentToken,
    Token enumKeyword,
    Token leftBrace,
  ) {
    seen(augmentToken);
    seen(enumKeyword);
    seen(leftBrace);
    doPrint(
      'handleEnumHeader('
      '$augmentToken, '
      '$enumKeyword, '
      '$leftBrace)',
    );
  }

  @override
  void beginEnumBody(Token token) {
    seen(token);
    doPrint(
      'beginEnumBody('
      '$token)',
    );
    indent++;
  }

  @override
  void endEnumBody(Token beginToken, Token endToken) {
    indent--;
    seen(beginToken);
    seen(endToken);
    doPrint(
      'endEnumBody('
      '$beginToken, '
      '$endToken)',
    );
  }

  @override
  void handleEnumElement(Token beginToken, Token? augmentToken) {
    seen(beginToken);
    seen(augmentToken);
    doPrint(
      'handleEnumElement('
      '$beginToken, '
      '$augmentToken)',
    );
  }

  @override
  void beginExport(Token token) {
    seen(token);
    doPrint(
      'beginExport('
      '$token)',
    );
    indent++;
  }

  @override
  void endExport(Token exportKeyword, Token semicolon) {
    indent--;
    seen(exportKeyword);
    seen(semicolon);
    doPrint(
      'endExport('
      '$exportKeyword, '
      '$semicolon)',
    );
  }

  @override
  void handleExtraneousExpression(Token token, Message message) {
    seen(token);
    doPrint(
      'handleExtraneousExpression('
      '$token, '
      '$message)',
    );
  }

  @override
  void handleExpressionStatement(Token beginToken, Token endToken) {
    seen(beginToken);
    seen(endToken);
    doPrint(
      'handleExpressionStatement('
      '$beginToken, '
      '$endToken)',
    );
  }

  @override
  void beginFactory(
    DeclarationKind declarationKind,
    Token lastConsumed,
    Token? externalToken,
    Token? constToken,
  ) {
    seen(lastConsumed);
    seen(externalToken);
    seen(constToken);
    doPrint(
      'beginFactory('
      '$declarationKind, '
      '$lastConsumed, '
      '$externalToken, '
      '$constToken)',
    );
    indent++;
  }

  @override
  void endFactory(
    DeclarationKind kind,
    Token beginToken,
    Token factoryKeyword,
    Token endToken,
  ) {
    indent--;
    seen(beginToken);
    seen(factoryKeyword);
    seen(endToken);
    doPrint(
      'endFactory('
      '$kind, '
      '$beginToken, '
      '$factoryKeyword, '
      '$endToken)',
    );
  }

  @override
  void beginFormalParameter(
    Token token,
    MemberKind kind,
    Token? requiredToken,
    Token? covariantToken,
    Token? varFinalOrConst,
  ) {
    seen(token);
    seen(requiredToken);
    seen(covariantToken);
    seen(varFinalOrConst);
    doPrint(
      'beginFormalParameter('
      '$token, '
      '$kind, '
      '$requiredToken, '
      '$covariantToken, '
      '$varFinalOrConst)',
    );
    indent++;
  }

  @override
  void endFormalParameter(
    Token? varOrFinal,
    Token? thisKeyword,
    Token? superKeyword,
    Token? periodAfterThisOrSuper,
    Token nameToken,
    Token? initializerStart,
    Token? initializerEnd,
    FormalParameterKind kind,
    MemberKind memberKind,
  ) {
    indent--;
    seen(varOrFinal);
    seen(thisKeyword);
    seen(superKeyword);
    seen(periodAfterThisOrSuper);
    seen(nameToken);
    seen(initializerStart);
    seen(initializerEnd);
    doPrint(
      'endFormalParameter('
      '$varOrFinal, '
      '$thisKeyword, '
      '$superKeyword, '
      '$periodAfterThisOrSuper, '
      '$nameToken, '
      '$initializerStart, '
      '$initializerEnd, '
      '$kind, '
      '$memberKind)',
    );
  }

  @override
  void handleNoFormalParameters(Token token, MemberKind kind) {
    seen(token);
    doPrint(
      'handleNoFormalParameters('
      '$token, '
      '$kind)',
    );
  }

  @override
  void beginFormalParameters(Token token, MemberKind kind) {
    seen(token);
    doPrint(
      'beginFormalParameters('
      '$token, '
      '$kind)',
    );
    indent++;
  }

  @override
  void endFormalParameters(
    int count,
    Token beginToken,
    Token endToken,
    MemberKind kind,
  ) {
    indent--;
    seen(beginToken);
    seen(endToken);
    doPrint(
      'endFormalParameters('
      '$count, '
      '$beginToken, '
      '$endToken, '
      '$kind)',
    );
  }

  @override
  void endFields(
    DeclarationKind kind,
    Token? abstractToken,
    Token? augmentToken,
    Token? externalToken,
    Token? staticToken,
    Token? covariantToken,
    Token? lateToken,
    Token? varFinalOrConst,
    int count,
    Token beginToken,
    Token endToken,
  ) {
    indent--;
    seen(abstractToken);
    seen(augmentToken);
    seen(externalToken);
    seen(staticToken);
    seen(covariantToken);
    seen(lateToken);
    seen(varFinalOrConst);
    seen(beginToken);
    seen(endToken);
    doPrint(
      'endFields('
      '$kind, '
      '$abstractToken, '
      '$augmentToken, '
      '$externalToken, '
      '$staticToken, '
      '$covariantToken, '
      '$lateToken, '
      '$varFinalOrConst, '
      '$count, '
      '$beginToken, '
      '$endToken)',
    );
  }

  @override
  void handleForInitializerEmptyStatement(Token token) {
    seen(token);
    doPrint(
      'handleForInitializerEmptyStatement('
      '$token)',
    );
  }

  @override
  void handleForInitializerExpressionStatement(Token token, bool forIn) {
    seen(token);
    doPrint(
      'handleForInitializerExpressionStatement('
      '$token, '
      '$forIn)',
    );
  }

  @override
  void handleForInitializerLocalVariableDeclaration(Token token, bool forIn) {
    seen(token);
    doPrint(
      'handleForInitializerLocalVariableDeclaration('
      '$token, '
      '$forIn)',
    );
  }

  @override
  void handleForInitializerPatternVariableAssignment(
    Token keyword,
    Token equals,
  ) {
    seen(keyword);
    seen(equals);
    doPrint(
      'handleForInitializerPatternVariableAssignment('
      '$keyword, '
      '$equals)',
    );
  }

  @override
  void beginForStatement(Token token) {
    seen(token);
    doPrint(
      'beginForStatement('
      '$token)',
    );
    indent++;
  }

  @override
  void handleForLoopParts(
    Token forKeyword,
    Token leftParen,
    Token leftSeparator,
    Token rightSeparator,
    int updateExpressionCount,
  ) {
    seen(forKeyword);
    seen(leftParen);
    seen(leftSeparator);
    seen(rightSeparator);
    doPrint(
      'handleForLoopParts('
      '$forKeyword, '
      '$leftParen, '
      '$leftSeparator, '
      '$rightSeparator, '
      '$updateExpressionCount)',
    );
  }

  @override
  void endForStatement(Token endToken) {
    indent--;
    seen(endToken);
    doPrint(
      'endForStatement('
      '$endToken)',
    );
  }

  @override
  void beginForStatementBody(Token token) {
    seen(token);
    doPrint(
      'beginForStatementBody('
      '$token)',
    );
    indent++;
  }

  @override
  void endForStatementBody(Token endToken) {
    indent--;
    seen(endToken);
    doPrint(
      'endForStatementBody('
      '$endToken)',
    );
  }

  @override
  void handleForInLoopParts(
    Token? awaitToken,
    Token forToken,
    Token leftParenthesis,
    Token? patternKeyword,
    Token inKeyword,
  ) {
    seen(awaitToken);
    seen(forToken);
    seen(leftParenthesis);
    seen(patternKeyword);
    seen(inKeyword);
    doPrint(
      'handleForInLoopParts('
      '$awaitToken, '
      '$forToken, '
      '$leftParenthesis, '
      '$patternKeyword, '
      '$inKeyword)',
    );
  }

  @override
  void endForIn(Token endToken) {
    indent--;
    seen(endToken);
    doPrint(
      'endForIn('
      '$endToken)',
    );
  }

  @override
  void beginForInExpression(Token token) {
    seen(token);
    doPrint(
      'beginForInExpression('
      '$token)',
    );
    indent++;
  }

  @override
  void endForInExpression(Token token) {
    indent--;
    seen(token);
    doPrint(
      'endForInExpression('
      '$token)',
    );
  }

  @override
  void beginForInBody(Token token) {
    seen(token);
    doPrint(
      'beginForInBody('
      '$token)',
    );
    indent++;
  }

  @override
  void endForInBody(Token endToken) {
    indent--;
    seen(endToken);
    doPrint(
      'endForInBody('
      '$endToken)',
    );
  }

  @override
  void beginNamedFunctionExpression(Token token) {
    seen(token);
    doPrint(
      'beginNamedFunctionExpression('
      '$token)',
    );
    indent++;
  }

  @override
  void endNamedFunctionExpression(Token endToken) {
    indent--;
    seen(endToken);
    doPrint(
      'endNamedFunctionExpression('
      '$endToken)',
    );
  }

  @override
  void beginLocalFunctionDeclaration(Token token) {
    seen(token);
    doPrint(
      'beginLocalFunctionDeclaration('
      '$token)',
    );
    indent++;
  }

  @override
  void endLocalFunctionDeclaration(Token endToken) {
    indent--;
    seen(endToken);
    doPrint(
      'endLocalFunctionDeclaration('
      '$endToken)',
    );
  }

  @override
  void beginBlockFunctionBody(Token token) {
    seen(token);
    doPrint(
      'beginBlockFunctionBody('
      '$token)',
    );
    indent++;
  }

  @override
  void endBlockFunctionBody(int count, Token beginToken, Token endToken) {
    indent--;
    seen(beginToken);
    seen(endToken);
    doPrint(
      'endBlockFunctionBody('
      '$count, '
      '$beginToken, '
      '$endToken)',
    );
  }

  @override
  void handleNoFunctionBody(Token token) {
    seen(token);
    doPrint(
      'handleNoFunctionBody('
      '$token)',
    );
  }

  @override
  void handleFunctionBodySkipped(Token token, bool isExpressionBody) {
    seen(token);
    doPrint(
      'handleFunctionBodySkipped('
      '$token, '
      '$isExpressionBody)',
    );
  }

  @override
  void beginFunctionName(Token token) {
    seen(token);
    doPrint(
      'beginFunctionName('
      '$token)',
    );
    indent++;
  }

  @override
  void endFunctionName(
    Token beginToken,
    Token token,
    bool isFunctionExpression,
  ) {
    indent--;
    seen(beginToken);
    seen(token);
    doPrint(
      'endFunctionName('
      '$beginToken, '
      '$token, '
      '$isFunctionExpression)',
    );
  }

  @override
  void beginTypedef(Token token) {
    seen(token);
    doPrint(
      'beginTypedef('
      '$token)',
    );
    indent++;
  }

  @override
  void endTypedef(
    Token? augmentToken,
    Token typedefKeyword,
    Token? equals,
    Token endToken,
  ) {
    indent--;
    seen(augmentToken);
    seen(typedefKeyword);
    seen(equals);
    seen(endToken);
    doPrint(
      'endTypedef('
      '$augmentToken, '
      '$typedefKeyword, '
      '$equals, '
      '$endToken)',
    );
  }

  @override
  void handleClassWithClause(Token withKeyword) {
    seen(withKeyword);
    doPrint(
      'handleClassWithClause('
      '$withKeyword)',
    );
  }

  @override
  void handleClassNoWithClause() {
    doPrint('handleClassNoWithClause()');
  }

  @override
  void handleEnumWithClause(Token withKeyword) {
    seen(withKeyword);
    doPrint(
      'handleEnumWithClause('
      '$withKeyword)',
    );
  }

  @override
  void handleEnumNoWithClause() {
    doPrint('handleEnumNoWithClause()');
  }

  @override
  void handleMixinWithClause(Token withKeyword) {
    seen(withKeyword);
    doPrint(
      'handleMixinWithClause('
      '$withKeyword)',
    );
  }

  @override
  void beginNamedMixinApplication(
    Token beginToken,
    Token? abstractToken,
    Token? macroToken,
    Token? sealedToken,
    Token? baseToken,
    Token? interfaceToken,
    Token? finalToken,
    Token? augmentToken,
    Token? mixinToken,
    Token name,
  ) {
    seen(beginToken);
    seen(abstractToken);
    seen(macroToken);
    seen(sealedToken);
    seen(baseToken);
    seen(interfaceToken);
    seen(finalToken);
    seen(augmentToken);
    seen(mixinToken);
    seen(name);
    doPrint(
      'beginNamedMixinApplication('
      '$beginToken, '
      '$abstractToken, '
      '$macroToken, '
      '$sealedToken, '
      '$baseToken, '
      '$interfaceToken, '
      '$finalToken, '
      '$augmentToken, '
      '$mixinToken, '
      '$name)',
    );
    indent++;
  }

  @override
  void handleNamedMixinApplicationWithClause(Token withKeyword) {
    seen(withKeyword);
    doPrint(
      'handleNamedMixinApplicationWithClause('
      '$withKeyword)',
    );
  }

  @override
  void endNamedMixinApplication(
    Token begin,
    Token classKeyword,
    Token equals,
    Token? implementsKeyword,
    Token endToken,
  ) {
    indent--;
    seen(begin);
    seen(classKeyword);
    seen(equals);
    seen(implementsKeyword);
    seen(endToken);
    doPrint(
      'endNamedMixinApplication('
      '$begin, '
      '$classKeyword, '
      '$equals, '
      '$implementsKeyword, '
      '$endToken)',
    );
  }

  @override
  void beginHide(Token hideKeyword) {
    seen(hideKeyword);
    doPrint(
      'beginHide('
      '$hideKeyword)',
    );
    indent++;
  }

  @override
  void endHide(Token hideKeyword) {
    indent--;
    seen(hideKeyword);
    doPrint(
      'endHide('
      '$hideKeyword)',
    );
  }

  @override
  void handleIdentifierList(int count) {
    doPrint(
      'handleIdentifierList('
      '$count)',
    );
  }

  @override
  void beginTypeList(Token token) {
    seen(token);
    doPrint(
      'beginTypeList('
      '$token)',
    );
    indent++;
  }

  @override
  void endTypeList(int count) {
    indent--;
    doPrint(
      'endTypeList('
      '$count)',
    );
  }

  @override
  void beginIfStatement(Token token) {
    seen(token);
    doPrint(
      'beginIfStatement('
      '$token)',
    );
    indent++;
  }

  @override
  void endIfStatement(Token ifToken, Token? elseToken, Token endToken) {
    indent--;
    seen(ifToken);
    seen(elseToken);
    seen(endToken);
    doPrint(
      'endIfStatement('
      '$ifToken, '
      '$elseToken, '
      '$endToken)',
    );
  }

  @override
  void beginThenStatement(Token token) {
    seen(token);
    doPrint(
      'beginThenStatement('
      '$token)',
    );
    indent++;
  }

  @override
  void endThenStatement(Token beginToken, Token endToken) {
    indent--;
    seen(beginToken);
    seen(endToken);
    doPrint(
      'endThenStatement('
      '$beginToken, '
      '$endToken)',
    );
  }

  @override
  void beginElseStatement(Token token) {
    seen(token);
    doPrint(
      'beginElseStatement('
      '$token)',
    );
    indent++;
  }

  @override
  void endElseStatement(Token beginToken, Token endToken) {
    indent--;
    seen(beginToken);
    seen(endToken);
    doPrint(
      'endElseStatement('
      '$beginToken, '
      '$endToken)',
    );
  }

  @override
  void beginImport(Token importKeyword) {
    seen(importKeyword);
    doPrint(
      'beginImport('
      '$importKeyword)',
    );
    indent++;
  }

  @override
  void handleImportPrefix(Token? deferredKeyword, Token? asKeyword) {
    seen(deferredKeyword);
    seen(asKeyword);
    doPrint(
      'handleImportPrefix('
      '$deferredKeyword, '
      '$asKeyword)',
    );
  }

  @override
  void endImport(Token importKeyword, Token? augmentToken, Token? semicolon) {
    indent--;
    seen(importKeyword);
    seen(augmentToken);
    seen(semicolon);
    doPrint(
      'endImport('
      '$importKeyword, '
      '$augmentToken, '
      '$semicolon)',
    );
  }

  @override
  void handleRecoverImport(Token? semicolon) {
    seen(semicolon);
    doPrint(
      'handleRecoverImport('
      '$semicolon)',
    );
  }

  @override
  void beginConditionalUris(Token token) {
    seen(token);
    doPrint(
      'beginConditionalUris('
      '$token)',
    );
    indent++;
  }

  @override
  void endConditionalUris(int count) {
    indent--;
    doPrint(
      'endConditionalUris('
      '$count)',
    );
  }

  @override
  void beginConditionalUri(Token ifKeyword) {
    seen(ifKeyword);
    doPrint(
      'beginConditionalUri('
      '$ifKeyword)',
    );
    indent++;
  }

  @override
  void endConditionalUri(Token ifKeyword, Token leftParen, Token? equalSign) {
    indent--;
    seen(ifKeyword);
    seen(leftParen);
    seen(equalSign);
    doPrint(
      'endConditionalUri('
      '$ifKeyword, '
      '$leftParen, '
      '$equalSign)',
    );
  }

  @override
  void handleDottedName(int count, Token firstIdentifier) {
    seen(firstIdentifier);
    doPrint(
      'handleDottedName('
      '$count, '
      '$firstIdentifier)',
    );
  }

  @override
  void beginImplicitCreationExpression(Token token) {
    seen(token);
    doPrint(
      'beginImplicitCreationExpression('
      '$token)',
    );
    indent++;
  }

  @override
  void endImplicitCreationExpression(Token token, Token openAngleBracket) {
    indent--;
    seen(token);
    seen(openAngleBracket);
    doPrint(
      'endImplicitCreationExpression('
      '$token, '
      '$openAngleBracket)',
    );
  }

  @override
  void beginInitializedIdentifier(Token token) {
    seen(token);
    doPrint(
      'beginInitializedIdentifier('
      '$token)',
    );
    indent++;
  }

  @override
  void endInitializedIdentifier(Token nameToken) {
    indent--;
    seen(nameToken);
    doPrint(
      'endInitializedIdentifier('
      '$nameToken)',
    );
  }

  @override
  void beginFieldInitializer(Token token) {
    seen(token);
    doPrint(
      'beginFieldInitializer('
      '$token)',
    );
    indent++;
  }

  @override
  void endFieldInitializer(Token assignment, Token endToken) {
    indent--;
    seen(assignment);
    seen(endToken);
    doPrint(
      'endFieldInitializer('
      '$assignment, '
      '$endToken)',
    );
  }

  @override
  void handleNoFieldInitializer(Token token) {
    seen(token);
    doPrint(
      'handleNoFieldInitializer('
      '$token)',
    );
  }

  @override
  void beginVariableInitializer(Token token) {
    seen(token);
    doPrint(
      'beginVariableInitializer('
      '$token)',
    );
    indent++;
  }

  @override
  void endVariableInitializer(Token assignmentOperator) {
    indent--;
    seen(assignmentOperator);
    doPrint(
      'endVariableInitializer('
      '$assignmentOperator)',
    );
  }

  @override
  void handleNoVariableInitializer(Token token) {
    seen(token);
    doPrint(
      'handleNoVariableInitializer('
      '$token)',
    );
  }

  @override
  void beginInitializer(Token token) {
    seen(token);
    doPrint(
      'beginInitializer('
      '$token)',
    );
    indent++;
  }

  @override
  void endInitializer(Token endToken) {
    indent--;
    seen(endToken);
    doPrint(
      'endInitializer('
      '$endToken)',
    );
  }

  @override
  void beginInitializers(Token token) {
    seen(token);
    doPrint(
      'beginInitializers('
      '$token)',
    );
    indent++;
  }

  @override
  void endInitializers(int count, Token beginToken, Token endToken) {
    indent--;
    seen(beginToken);
    seen(endToken);
    doPrint(
      'endInitializers('
      '$count, '
      '$beginToken, '
      '$endToken)',
    );
  }

  @override
  void handleNoInitializers() {
    doPrint('handleNoInitializers()');
  }

  @override
  void handleInvalidExpression(Token token) {
    seen(token);
    doPrint(
      'handleInvalidExpression('
      '$token)',
    );
  }

  @override
  void handleInvalidFunctionBody(Token token) {
    seen(token);
    doPrint(
      'handleInvalidFunctionBody('
      '$token)',
    );
  }

  @override
  void handleInvalidTypeReference(Token token) {
    seen(token);
    doPrint(
      'handleInvalidTypeReference('
      '$token)',
    );
  }

  @override
  void handleLabel(Token token) {
    seen(token);
    doPrint(
      'handleLabel('
      '$token)',
    );
  }

  @override
  void beginLabeledStatement(Token token, int labelCount) {
    seen(token);
    doPrint(
      'beginLabeledStatement('
      '$token, '
      '$labelCount)',
    );
    indent++;
  }

  @override
  void endLabeledStatement(int labelCount) {
    indent--;
    doPrint(
      'endLabeledStatement('
      '$labelCount)',
    );
  }

  @override
  void beginLibraryAugmentation(Token augmentKeyword, Token libraryKeyword) {
    seen(augmentKeyword);
    seen(libraryKeyword);
    doPrint(
      'beginLibraryAugmentation('
      '$augmentKeyword, '
      '$libraryKeyword)',
    );
    indent++;
  }

  @override
  void endLibraryAugmentation(
    Token augmentKeyword,
    Token libraryKeyword,
    Token semicolon,
  ) {
    indent--;
    seen(augmentKeyword);
    seen(libraryKeyword);
    seen(semicolon);
    doPrint(
      'endLibraryAugmentation('
      '$augmentKeyword, '
      '$libraryKeyword, '
      '$semicolon)',
    );
  }

  @override
  void beginLibraryName(Token token) {
    seen(token);
    doPrint(
      'beginLibraryName('
      '$token)',
    );
    indent++;
  }

  @override
  void endLibraryName(Token libraryKeyword, Token semicolon, bool hasName) {
    indent--;
    seen(libraryKeyword);
    seen(semicolon);
    doPrint(
      'endLibraryName('
      '$libraryKeyword, '
      '$semicolon, '
      '$hasName)',
    );
  }

  @override
  void handleLiteralMapEntry(
    Token colon,
    Token endToken, {
    Token? nullAwareKeyToken,
    Token? nullAwareValueToken,
  }) {
    seen(colon);
    seen(endToken);
    seen(nullAwareKeyToken);
    seen(nullAwareValueToken);
    doPrint(
      'handleLiteralMapEntry('
      '$colon, '
      '$endToken, '
      '$nullAwareKeyToken, '
      '$nullAwareValueToken)',
    );
  }

  @override
  void handleMapPatternEntry(Token colon, Token endToken) {
    seen(colon);
    seen(endToken);
    doPrint(
      'handleMapPatternEntry('
      '$colon, '
      '$endToken)',
    );
  }

  @override
  void beginLiteralString(Token token) {
    seen(token);
    doPrint(
      'beginLiteralString('
      '$token)',
    );
    indent++;
  }

  @override
  void handleInterpolationExpression(Token leftBracket, Token? rightBracket) {
    seen(leftBracket);
    seen(rightBracket);
    doPrint(
      'handleInterpolationExpression('
      '$leftBracket, '
      '$rightBracket)',
    );
  }

  @override
  void endLiteralString(int interpolationCount, Token endToken) {
    indent--;
    seen(endToken);
    doPrint(
      'endLiteralString('
      '$interpolationCount, '
      '$endToken)',
    );
  }

  @override
  void handleAdjacentStringLiterals(Token startToken, int literalCount) {
    seen(startToken);
    doPrint(
      'handleAdjacentStringLiterals('
      '$startToken, '
      '$literalCount)',
    );
  }

  @override
  void beginMember() {
    doPrint('beginMember()');
    indent++;
  }

  @override
  void handleInvalidMember(Token endToken) {
    seen(endToken);
    doPrint(
      'handleInvalidMember('
      '$endToken)',
    );
  }

  @override
  void endMember() {
    indent--;
    doPrint('endMember()');
  }

  @override
  void beginMethod(
    DeclarationKind declarationKind,
    Token? augmentToken,
    Token? externalToken,
    Token? staticToken,
    Token? covariantToken,
    Token? varFinalOrConst,
    Token? getOrSet,
    Token name,
    String? enclosingDeclarationName,
  ) {
    seen(augmentToken);
    seen(externalToken);
    seen(staticToken);
    seen(covariantToken);
    seen(varFinalOrConst);
    seen(getOrSet);
    seen(name);
    doPrint(
      'beginMethod('
      '$declarationKind, '
      '$augmentToken, '
      '$externalToken, '
      '$staticToken, '
      '$covariantToken, '
      '$varFinalOrConst, '
      '$getOrSet, '
      '$name, '
      '$enclosingDeclarationName)',
    );
    indent++;
  }

  @override
  void endMethod(
    DeclarationKind kind,
    Token? getOrSet,
    Token beginToken,
    Token beginParam,
    Token? beginInitializers,
    Token endToken,
  ) {
    indent--;
    seen(getOrSet);
    seen(beginToken);
    seen(beginParam);
    seen(beginInitializers);
    seen(endToken);
    doPrint(
      'endMethod('
      '$kind, '
      '$getOrSet, '
      '$beginToken, '
      '$beginParam, '
      '$beginInitializers, '
      '$endToken)',
    );
  }

  @override
  void beginConstructor(
    DeclarationKind declarationKind,
    Token? augmentToken,
    Token? externalToken,
    Token? staticToken,
    Token? covariantToken,
    Token? varFinalOrConst,
    Token? getOrSet,
    Token? newToken,
    Token name,
    String? enclosingDeclarationName,
  ) {
    seen(augmentToken);
    seen(externalToken);
    seen(staticToken);
    seen(covariantToken);
    seen(varFinalOrConst);
    seen(getOrSet);
    seen(newToken);
    seen(name);
    doPrint(
      'beginConstructor('
      '$declarationKind, '
      '$augmentToken, '
      '$externalToken, '
      '$staticToken, '
      '$covariantToken, '
      '$varFinalOrConst, '
      '$getOrSet, '
      '$newToken, '
      '$name, '
      '$enclosingDeclarationName)',
    );
    indent++;
  }

  @override
  void endConstructor(
    DeclarationKind kind,
    Token beginToken,
    Token? newToken,
    Token beginParam,
    Token? beginInitializers,
    Token endToken,
  ) {
    indent--;
    seen(beginToken);
    seen(newToken);
    seen(beginParam);
    seen(beginInitializers);
    seen(endToken);
    doPrint(
      'endConstructor('
      '$kind, '
      '$beginToken, '
      '$newToken, '
      '$beginParam, '
      '$beginInitializers, '
      '$endToken)',
    );
  }

  @override
  void beginMetadataStar(Token token) {
    seen(token);
    doPrint(
      'beginMetadataStar('
      '$token)',
    );
    indent++;
  }

  @override
  void endMetadataStar(int count) {
    indent--;
    doPrint(
      'endMetadataStar('
      '$count)',
    );
  }

  @override
  void beginMetadata(Token token) {
    seen(token);
    doPrint(
      'beginMetadata('
      '$token)',
    );
    indent++;
  }

  @override
  void endMetadata(Token beginToken, Token? periodBeforeName, Token endToken) {
    indent--;
    seen(beginToken);
    seen(periodBeforeName);
    seen(endToken);
    doPrint(
      'endMetadata('
      '$beginToken, '
      '$periodBeforeName, '
      '$endToken)',
    );
  }

  @override
  void beginOptionalFormalParameters(Token token) {
    seen(token);
    doPrint(
      'beginOptionalFormalParameters('
      '$token)',
    );
    indent++;
  }

  @override
  void endOptionalFormalParameters(
    int count,
    Token beginToken,
    Token endToken,
    MemberKind kind,
  ) {
    indent--;
    seen(beginToken);
    seen(endToken);
    doPrint(
      'endOptionalFormalParameters('
      '$count, '
      '$beginToken, '
      '$endToken, '
      '$kind)',
    );
  }

  @override
  void beginPart(Token token) {
    seen(token);
    doPrint(
      'beginPart('
      '$token)',
    );
    indent++;
  }

  @override
  void endPart(Token partKeyword, Token semicolon) {
    indent--;
    seen(partKeyword);
    seen(semicolon);
    doPrint(
      'endPart('
      '$partKeyword, '
      '$semicolon)',
    );
  }

  @override
  void beginPartOf(Token token) {
    seen(token);
    doPrint(
      'beginPartOf('
      '$token)',
    );
    indent++;
  }

  @override
  void endPartOf(
    Token partKeyword,
    Token ofKeyword,
    Token semicolon,
    bool hasName,
  ) {
    indent--;
    seen(partKeyword);
    seen(ofKeyword);
    seen(semicolon);
    doPrint(
      'endPartOf('
      '$partKeyword, '
      '$ofKeyword, '
      '$semicolon, '
      '$hasName)',
    );
  }

  @override
  void beginRedirectingFactoryBody(Token token) {
    seen(token);
    doPrint(
      'beginRedirectingFactoryBody('
      '$token)',
    );
    indent++;
  }

  @override
  void endRedirectingFactoryBody(Token beginToken, Token endToken) {
    indent--;
    seen(beginToken);
    seen(endToken);
    doPrint(
      'endRedirectingFactoryBody('
      '$beginToken, '
      '$endToken)',
    );
  }

  @override
  void beginReturnStatement(Token token) {
    seen(token);
    doPrint(
      'beginReturnStatement('
      '$token)',
    );
    indent++;
  }

  @override
  void handleNativeFunctionBody(Token nativeToken, Token semicolon) {
    seen(nativeToken);
    seen(semicolon);
    doPrint(
      'handleNativeFunctionBody('
      '$nativeToken, '
      '$semicolon)',
    );
  }

  @override
  void handleNativeFunctionBodyIgnored(Token nativeToken, Token semicolon) {
    seen(nativeToken);
    seen(semicolon);
    doPrint(
      'handleNativeFunctionBodyIgnored('
      '$nativeToken, '
      '$semicolon)',
    );
  }

  @override
  void handleNativeFunctionBodySkipped(Token nativeToken, Token semicolon) {
    seen(nativeToken);
    seen(semicolon);
    doPrint(
      'handleNativeFunctionBodySkipped('
      '$nativeToken, '
      '$semicolon)',
    );
  }

  @override
  void handleEmptyFunctionBody(Token semicolon) {
    seen(semicolon);
    doPrint(
      'handleEmptyFunctionBody('
      '$semicolon)',
    );
  }

  @override
  void handleExpressionFunctionBody(Token arrowToken, Token? endToken) {
    seen(arrowToken);
    seen(endToken);
    doPrint(
      'handleExpressionFunctionBody('
      '$arrowToken, '
      '$endToken)',
    );
  }

  @override
  void endReturnStatement(
    bool hasExpression,
    Token beginToken,
    Token endToken,
  ) {
    indent--;
    seen(beginToken);
    seen(endToken);
    doPrint(
      'endReturnStatement('
      '$hasExpression, '
      '$beginToken, '
      '$endToken)',
    );
  }

  @override
  void handleSend(Token beginToken, Token endToken) {
    seen(beginToken);
    seen(endToken);
    doPrint(
      'handleSend('
      '$beginToken, '
      '$endToken)',
    );
  }

  @override
  void beginShow(Token showKeyword) {
    seen(showKeyword);
    doPrint(
      'beginShow('
      '$showKeyword)',
    );
    indent++;
  }

  @override
  void endShow(Token showKeyword) {
    indent--;
    seen(showKeyword);
    doPrint(
      'endShow('
      '$showKeyword)',
    );
  }

  @override
  void beginSwitchStatement(Token token) {
    seen(token);
    doPrint(
      'beginSwitchStatement('
      '$token)',
    );
    indent++;
  }

  @override
  void endSwitchStatement(Token switchKeyword, Token endToken) {
    indent--;
    seen(switchKeyword);
    seen(endToken);
    doPrint(
      'endSwitchStatement('
      '$switchKeyword, '
      '$endToken)',
    );
  }

  @override
  void beginSwitchExpression(Token token) {
    seen(token);
    doPrint(
      'beginSwitchExpression('
      '$token)',
    );
    indent++;
  }

  @override
  void endSwitchExpression(Token switchKeyword, Token endToken) {
    indent--;
    seen(switchKeyword);
    seen(endToken);
    doPrint(
      'endSwitchExpression('
      '$switchKeyword, '
      '$endToken)',
    );
  }

  @override
  void beginSwitchBlock(Token token) {
    seen(token);
    doPrint(
      'beginSwitchBlock('
      '$token)',
    );
    indent++;
  }

  @override
  void endSwitchBlock(int caseCount, Token beginToken, Token endToken) {
    indent--;
    seen(beginToken);
    seen(endToken);
    doPrint(
      'endSwitchBlock('
      '$caseCount, '
      '$beginToken, '
      '$endToken)',
    );
  }

  @override
  void beginSwitchExpressionBlock(Token token) {
    seen(token);
    doPrint(
      'beginSwitchExpressionBlock('
      '$token)',
    );
    indent++;
  }

  @override
  void endSwitchExpressionBlock(
    int caseCount,
    Token beginToken,
    Token endToken,
  ) {
    indent--;
    seen(beginToken);
    seen(endToken);
    doPrint(
      'endSwitchExpressionBlock('
      '$caseCount, '
      '$beginToken, '
      '$endToken)',
    );
  }

  @override
  void beginLiteralSymbol(Token token) {
    seen(token);
    doPrint(
      'beginLiteralSymbol('
      '$token)',
    );
    indent++;
  }

  @override
  void endLiteralSymbol(Token hashToken, int identifierCount) {
    indent--;
    seen(hashToken);
    doPrint(
      'endLiteralSymbol('
      '$hashToken, '
      '$identifierCount)',
    );
  }

  @override
  void handleThrowExpression(Token throwToken, Token endToken) {
    seen(throwToken);
    seen(endToken);
    doPrint(
      'handleThrowExpression('
      '$throwToken, '
      '$endToken)',
    );
  }

  @override
  void beginRethrowStatement(Token token) {
    seen(token);
    doPrint(
      'beginRethrowStatement('
      '$token)',
    );
    indent++;
  }

  @override
  void endRethrowStatement(Token rethrowToken, Token endToken) {
    indent--;
    seen(rethrowToken);
    seen(endToken);
    doPrint(
      'endRethrowStatement('
      '$rethrowToken, '
      '$endToken)',
    );
  }

  @override
  void endTopLevelDeclaration(Token endToken) {
    indent--;
    seen(endToken);
    doPrint(
      'endTopLevelDeclaration('
      '$endToken)',
    );
  }

  @override
  void handleInvalidTopLevelDeclaration(Token endToken) {
    seen(endToken);
    doPrint(
      'handleInvalidTopLevelDeclaration('
      '$endToken)',
    );
  }

  @override
  void beginTopLevelMember(Token token) {
    seen(token);
    doPrint(
      'beginTopLevelMember('
      '$token)',
    );
    indent++;
  }

  @override
  void beginFields(
    DeclarationKind declarationKind,
    Token? abstractToken,
    Token? augmentToken,
    Token? externalToken,
    Token? staticToken,
    Token? covariantToken,
    Token? lateToken,
    Token? varFinalOrConst,
    Token lastConsumed,
  ) {
    seen(abstractToken);
    seen(augmentToken);
    seen(externalToken);
    seen(staticToken);
    seen(covariantToken);
    seen(lateToken);
    seen(varFinalOrConst);
    seen(lastConsumed);
    doPrint(
      'beginFields('
      '$declarationKind, '
      '$abstractToken, '
      '$augmentToken, '
      '$externalToken, '
      '$staticToken, '
      '$covariantToken, '
      '$lateToken, '
      '$varFinalOrConst, '
      '$lastConsumed)',
    );
    indent++;
  }

  @override
  void endTopLevelFields(
    Token? augmentToken,
    Token? externalToken,
    Token? staticToken,
    Token? covariantToken,
    Token? lateToken,
    Token? varFinalOrConst,
    int count,
    Token beginToken,
    Token endToken,
  ) {
    indent--;
    seen(augmentToken);
    seen(externalToken);
    seen(staticToken);
    seen(covariantToken);
    seen(lateToken);
    seen(varFinalOrConst);
    seen(beginToken);
    seen(endToken);
    doPrint(
      'endTopLevelFields('
      '$augmentToken, '
      '$externalToken, '
      '$staticToken, '
      '$covariantToken, '
      '$lateToken, '
      '$varFinalOrConst, '
      '$count, '
      '$beginToken, '
      '$endToken)',
    );
  }

  @override
  void beginTopLevelMethod(
    Token lastConsumed,
    Token? augmentToken,
    Token? externalToken,
  ) {
    seen(lastConsumed);
    seen(augmentToken);
    seen(externalToken);
    doPrint(
      'beginTopLevelMethod('
      '$lastConsumed, '
      '$augmentToken, '
      '$externalToken)',
    );
    indent++;
  }

  @override
  void endTopLevelMethod(Token beginToken, Token? getOrSet, Token endToken) {
    indent--;
    seen(beginToken);
    seen(getOrSet);
    seen(endToken);
    doPrint(
      'endTopLevelMethod('
      '$beginToken, '
      '$getOrSet, '
      '$endToken)',
    );
  }

  @override
  void beginTryStatement(Token token) {
    seen(token);
    doPrint(
      'beginTryStatement('
      '$token)',
    );
    indent++;
  }

  @override
  void beginCatchClause(Token token) {
    seen(token);
    doPrint(
      'beginCatchClause('
      '$token)',
    );
    indent++;
  }

  @override
  void endCatchClause(Token token) {
    indent--;
    seen(token);
    doPrint(
      'endCatchClause('
      '$token)',
    );
  }

  @override
  void handleCatchBlock(Token? onKeyword, Token? catchKeyword, Token? comma) {
    seen(onKeyword);
    seen(catchKeyword);
    seen(comma);
    doPrint(
      'handleCatchBlock('
      '$onKeyword, '
      '$catchKeyword, '
      '$comma)',
    );
  }

  @override
  void handleFinallyBlock(Token finallyKeyword) {
    seen(finallyKeyword);
    doPrint(
      'handleFinallyBlock('
      '$finallyKeyword)',
    );
  }

  @override
  void endTryStatement(
    int catchCount,
    Token tryKeyword,
    Token? finallyKeyword,
    Token endToken,
  ) {
    indent--;
    seen(tryKeyword);
    seen(finallyKeyword);
    seen(endToken);
    doPrint(
      'endTryStatement('
      '$catchCount, '
      '$tryKeyword, '
      '$finallyKeyword, '
      '$endToken)',
    );
  }

  @override
  void handleType(Token beginToken, Token? questionMark) {
    seen(beginToken);
    seen(questionMark);
    doPrint(
      'handleType('
      '$beginToken, '
      '$questionMark)',
    );
  }

  @override
  void handleNonNullAssertExpression(Token bang) {
    seen(bang);
    doPrint(
      'handleNonNullAssertExpression('
      '$bang)',
    );
  }

  @override
  void handleNullAssertPattern(Token bang) {
    seen(bang);
    doPrint(
      'handleNullAssertPattern('
      '$bang)',
    );
  }

  @override
  void handleNullCheckPattern(Token question) {
    seen(question);
    doPrint(
      'handleNullCheckPattern('
      '$question)',
    );
  }

  @override
  void handleAssignedVariablePattern(Token variable) {
    seen(variable);
    doPrint(
      'handleAssignedVariablePattern('
      '$variable)',
    );
  }

  @override
  void handleDeclaredVariablePattern(
    Token? keyword,
    Token variable, {
    required bool inAssignmentPattern,
  }) {
    seen(keyword);
    seen(variable);
    doPrint(
      'handleDeclaredVariablePattern('
      '$keyword, '
      '$variable, '
      '$inAssignmentPattern)',
    );
  }

  @override
  void handleWildcardPattern(Token? keyword, Token wildcard) {
    seen(keyword);
    seen(wildcard);
    doPrint(
      'handleWildcardPattern('
      '$keyword, '
      '$wildcard)',
    );
  }

  @override
  void handleNoName(Token token) {
    seen(token);
    doPrint(
      'handleNoName('
      '$token)',
    );
  }

  @override
  void beginRecordType(Token leftBracket) {
    seen(leftBracket);
    doPrint(
      'beginRecordType('
      '$leftBracket)',
    );
    indent++;
  }

  @override
  void endRecordType(
    Token leftBracket,
    Token? questionMark,
    int count,
    bool hasNamedFields,
  ) {
    indent--;
    seen(leftBracket);
    seen(questionMark);
    doPrint(
      'endRecordType('
      '$leftBracket, '
      '$questionMark, '
      '$count, '
      '$hasNamedFields)',
    );
  }

  @override
  void beginRecordTypeEntry() {
    doPrint('beginRecordTypeEntry()');
    indent++;
  }

  @override
  void endRecordTypeEntry() {
    indent--;
    doPrint('endRecordTypeEntry()');
  }

  @override
  void beginRecordTypeNamedFields(Token leftBracket) {
    seen(leftBracket);
    doPrint(
      'beginRecordTypeNamedFields('
      '$leftBracket)',
    );
    indent++;
  }

  @override
  void endRecordTypeNamedFields(int count, Token leftBracket) {
    indent--;
    seen(leftBracket);
    doPrint(
      'endRecordTypeNamedFields('
      '$count, '
      '$leftBracket)',
    );
  }

  @override
  void beginFunctionType(Token beginToken) {
    seen(beginToken);
    doPrint(
      'beginFunctionType('
      '$beginToken)',
    );
    indent++;
  }

  @override
  void endFunctionType(Token functionToken, Token? questionMark) {
    indent--;
    seen(functionToken);
    seen(questionMark);
    doPrint(
      'endFunctionType('
      '$functionToken, '
      '$questionMark)',
    );
  }

  @override
  void beginTypeArguments(Token token) {
    seen(token);
    doPrint(
      'beginTypeArguments('
      '$token)',
    );
    indent++;
  }

  @override
  void endTypeArguments(int count, Token beginToken, Token endToken) {
    indent--;
    seen(beginToken);
    seen(endToken);
    doPrint(
      'endTypeArguments('
      '$count, '
      '$beginToken, '
      '$endToken)',
    );
  }

  @override
  void handleInvalidTypeArguments(Token token) {
    seen(token);
    doPrint(
      'handleInvalidTypeArguments('
      '$token)',
    );
  }

  @override
  void handleNoTypeArguments(Token token) {
    seen(token);
    doPrint(
      'handleNoTypeArguments('
      '$token)',
    );
  }

  @override
  void beginTypeVariable(Token token) {
    seen(token);
    doPrint(
      'beginTypeVariable('
      '$token)',
    );
    indent++;
  }

  @override
  void handleTypeVariablesDefined(Token token, int count) {
    seen(token);
    doPrint(
      'handleTypeVariablesDefined('
      '$token, '
      '$count)',
    );
  }

  @override
  void endTypeVariable(
    Token token,
    int index,
    Token? extendsOrSuper,
    Token? variance,
  ) {
    indent--;
    seen(token);
    seen(extendsOrSuper);
    seen(variance);
    doPrint(
      'endTypeVariable('
      '$token, '
      '$index, '
      '$extendsOrSuper, '
      '$variance)',
    );
  }

  @override
  void beginTypeVariables(Token token) {
    seen(token);
    doPrint(
      'beginTypeVariables('
      '$token)',
    );
    indent++;
  }

  @override
  void endTypeVariables(Token beginToken, Token endToken) {
    indent--;
    seen(beginToken);
    seen(endToken);
    doPrint(
      'endTypeVariables('
      '$beginToken, '
      '$endToken)',
    );
  }

  @override
  void reportVarianceModifierNotEnabled(Token? variance) {
    seen(variance);
    doPrint(
      'reportVarianceModifierNotEnabled('
      '$variance)',
    );
  }

  @override
  void beginFunctionExpression(Token token) {
    seen(token);
    doPrint(
      'beginFunctionExpression('
      '$token)',
    );
    indent++;
  }

  @override
  void endFunctionExpression(Token beginToken, Token endToken) {
    indent--;
    seen(beginToken);
    seen(endToken);
    doPrint(
      'endFunctionExpression('
      '$beginToken, '
      '$endToken)',
    );
  }

  @override
  void beginVariablesDeclaration(
    Token token,
    Token? lateToken,
    Token? varFinalOrConst,
  ) {
    seen(token);
    seen(lateToken);
    seen(varFinalOrConst);
    doPrint(
      'beginVariablesDeclaration('
      '$token, '
      '$lateToken, '
      '$varFinalOrConst)',
    );
    indent++;
  }

  @override
  void endVariablesDeclaration(int count, Token? endToken) {
    indent--;
    seen(endToken);
    doPrint(
      'endVariablesDeclaration('
      '$count, '
      '$endToken)',
    );
  }

  @override
  void beginWhileStatement(Token token) {
    seen(token);
    doPrint(
      'beginWhileStatement('
      '$token)',
    );
    indent++;
  }

  @override
  void endWhileStatement(Token whileKeyword, Token endToken) {
    indent--;
    seen(whileKeyword);
    seen(endToken);
    doPrint(
      'endWhileStatement('
      '$whileKeyword, '
      '$endToken)',
    );
  }

  @override
  void beginAsOperatorType(Token operator) {
    seen(operator);
    doPrint(
      'beginAsOperatorType('
      '$operator)',
    );
    indent++;
  }

  @override
  void endAsOperatorType(Token operator) {
    indent--;
    seen(operator);
    doPrint(
      'endAsOperatorType('
      '$operator)',
    );
  }

  @override
  void handleAsOperator(Token operator) {
    seen(operator);
    doPrint(
      'handleAsOperator('
      '$operator)',
    );
  }

  @override
  void handleCastPattern(Token operator) {
    seen(operator);
    doPrint(
      'handleCastPattern('
      '$operator)',
    );
  }

  @override
  void handleAssignmentExpression(Token token, Token endToken) {
    seen(token);
    seen(endToken);
    doPrint(
      'handleAssignmentExpression('
      '$token, '
      '$endToken)',
    );
  }

  @override
  void beginAnonymousMethodInvocation(Token token) {
    seen(token);
    doPrint(
      'beginAnonymousMethodInvocation('
      '$token)',
    );
    indent++;
  }

  @override
  void endAnonymousMethodInvocation(
    Token beginToken,
    Token? functionDefinition,
    Token endToken, {
    required bool isExpression,
  }) {
    indent--;
    seen(beginToken);
    seen(functionDefinition);
    seen(endToken);
    doPrint(
      'endAnonymousMethodInvocation('
      '$beginToken, '
      '$functionDefinition, '
      '$endToken, '
      '$isExpression)',
    );
  }

  @override
  void handleImplicitFormalParameters(Token token) {
    seen(token);
    doPrint(
      'handleImplicitFormalParameters('
      '$token)',
    );
  }

  @override
  void beginBinaryExpression(Token token) {
    seen(token);
    doPrint(
      'beginBinaryExpression('
      '$token)',
    );
    indent++;
  }

  @override
  void endBinaryExpression(Token token, Token endToken) {
    indent--;
    seen(token);
    seen(endToken);
    doPrint(
      'endBinaryExpression('
      '$token, '
      '$endToken)',
    );
  }

  @override
  void beginBinaryPattern(Token token) {
    seen(token);
    doPrint(
      'beginBinaryPattern('
      '$token)',
    );
    indent++;
  }

  @override
  void endBinaryPattern(Token token) {
    indent--;
    seen(token);
    doPrint(
      'endBinaryPattern('
      '$token)',
    );
  }

  @override
  void handleDotAccess(Token token, Token endToken, bool isNullAware) {
    seen(token);
    seen(endToken);
    doPrint(
      'handleDotAccess('
      '$token, '
      '$endToken, '
      '$isNullAware)',
    );
  }

  @override
  void handleCascadeAccess(Token token, Token endToken, bool isNullAware) {
    seen(token);
    seen(endToken);
    doPrint(
      'handleCascadeAccess('
      '$token, '
      '$endToken, '
      '$isNullAware)',
    );
  }

  @override
  void beginConditionalExpression(Token question) {
    seen(question);
    doPrint(
      'beginConditionalExpression('
      '$question)',
    );
    indent++;
  }

  @override
  void handleConditionalExpressionColon() {
    doPrint('handleConditionalExpressionColon()');
  }

  @override
  void endConditionalExpression(Token question, Token colon, Token endToken) {
    indent--;
    seen(question);
    seen(colon);
    seen(endToken);
    doPrint(
      'endConditionalExpression('
      '$question, '
      '$colon, '
      '$endToken)',
    );
  }

  @override
  void beginConstExpression(Token constKeyword) {
    seen(constKeyword);
    doPrint(
      'beginConstExpression('
      '$constKeyword)',
    );
    indent++;
  }

  @override
  void endConstExpression(Token token) {
    indent--;
    seen(token);
    doPrint(
      'endConstExpression('
      '$token)',
    );
  }

  @override
  void handleConstFactory(Token constKeyword) {
    seen(constKeyword);
    doPrint(
      'handleConstFactory('
      '$constKeyword)',
    );
  }

  @override
  void beginForControlFlow(Token? awaitToken, Token forToken) {
    seen(awaitToken);
    seen(forToken);
    doPrint(
      'beginForControlFlow('
      '$awaitToken, '
      '$forToken)',
    );
    indent++;
  }

  @override
  void endForControlFlow(Token token) {
    indent--;
    seen(token);
    doPrint(
      'endForControlFlow('
      '$token)',
    );
  }

  @override
  void endForInControlFlow(Token token) {
    indent--;
    seen(token);
    doPrint(
      'endForInControlFlow('
      '$token)',
    );
  }

  @override
  void beginIfControlFlow(Token ifToken) {
    seen(ifToken);
    doPrint(
      'beginIfControlFlow('
      '$ifToken)',
    );
    indent++;
  }

  @override
  void handleThenControlFlow(Token token) {
    seen(token);
    doPrint(
      'handleThenControlFlow('
      '$token)',
    );
  }

  @override
  void handleElseControlFlow(Token elseToken) {
    seen(elseToken);
    doPrint(
      'handleElseControlFlow('
      '$elseToken)',
    );
  }

  @override
  void endIfControlFlow(Token token) {
    indent--;
    seen(token);
    doPrint(
      'endIfControlFlow('
      '$token)',
    );
  }

  @override
  void endIfElseControlFlow(Token token) {
    indent--;
    seen(token);
    doPrint(
      'endIfElseControlFlow('
      '$token)',
    );
  }

  @override
  void handleSpreadExpression(Token spreadToken) {
    seen(spreadToken);
    doPrint(
      'handleSpreadExpression('
      '$spreadToken)',
    );
  }

  @override
  void handleNullAwareElement(Token nullAwareToken) {
    seen(nullAwareToken);
    doPrint(
      'handleNullAwareElement('
      '$nullAwareToken)',
    );
  }

  @override
  void handleRestPattern(Token dots, {required bool hasSubPattern}) {
    seen(dots);
    doPrint(
      'handleRestPattern('
      '$dots, '
      '$hasSubPattern)',
    );
  }

  @override
  void beginFunctionTypedFormalParameter(Token token) {
    seen(token);
    doPrint(
      'beginFunctionTypedFormalParameter('
      '$token)',
    );
    indent++;
  }

  @override
  void endFunctionTypedFormalParameter(Token nameToken, Token? question) {
    indent--;
    seen(nameToken);
    seen(question);
    doPrint(
      'endFunctionTypedFormalParameter('
      '$nameToken, '
      '$question)',
    );
  }

  @override
  void handleIdentifier(Token token, IdentifierContext context) {
    seen(token);
    doPrint(
      'handleIdentifier('
      '$token, '
      '$context)',
    );
  }

  @override
  void handleIndexedExpression(
    Token? question,
    Token openSquareBracket,
    Token closeSquareBracket,
  ) {
    seen(question);
    seen(openSquareBracket);
    seen(closeSquareBracket);
    doPrint(
      'handleIndexedExpression('
      '$question, '
      '$openSquareBracket, '
      '$closeSquareBracket)',
    );
  }

  @override
  void beginIsOperatorType(Token operator) {
    seen(operator);
    doPrint(
      'beginIsOperatorType('
      '$operator)',
    );
    indent++;
  }

  @override
  void endIsOperatorType(Token operator) {
    indent--;
    seen(operator);
    doPrint(
      'endIsOperatorType('
      '$operator)',
    );
  }

  @override
  void handleIsOperator(Token isOperator, Token? not) {
    seen(isOperator);
    seen(not);
    doPrint(
      'handleIsOperator('
      '$isOperator, '
      '$not)',
    );
  }

  @override
  void handleLiteralBool(Token token) {
    seen(token);
    doPrint(
      'handleLiteralBool('
      '$token)',
    );
  }

  @override
  void handleBreakStatement(
    bool hasTarget,
    Token breakKeyword,
    Token endToken,
  ) {
    seen(breakKeyword);
    seen(endToken);
    doPrint(
      'handleBreakStatement('
      '$hasTarget, '
      '$breakKeyword, '
      '$endToken)',
    );
  }

  @override
  void handleContinueStatement(
    bool hasTarget,
    Token continueKeyword,
    Token endToken,
  ) {
    seen(continueKeyword);
    seen(endToken);
    doPrint(
      'handleContinueStatement('
      '$hasTarget, '
      '$continueKeyword, '
      '$endToken)',
    );
  }

  @override
  void handleEmptyStatement(Token token) {
    seen(token);
    doPrint(
      'handleEmptyStatement('
      '$token)',
    );
  }

  @override
  void beginAssert(Token assertKeyword, Assert kind) {
    seen(assertKeyword);
    doPrint(
      'beginAssert('
      '$assertKeyword, '
      '$kind)',
    );
    indent++;
  }

  @override
  void endAssert(
    Token assertKeyword,
    Assert kind,
    Token leftParenthesis,
    Token? commaToken,
    Token endToken,
  ) {
    indent--;
    seen(assertKeyword);
    seen(leftParenthesis);
    seen(commaToken);
    seen(endToken);
    doPrint(
      'endAssert('
      '$assertKeyword, '
      '$kind, '
      '$leftParenthesis, '
      '$commaToken, '
      '$endToken)',
    );
  }

  @override
  void handleLiteralDouble(Token token) {
    seen(token);
    doPrint(
      'handleLiteralDouble('
      '$token)',
    );
  }

  @override
  void handleLiteralDoubleWithSeparators(Token token) {
    seen(token);
    doPrint(
      'handleLiteralDoubleWithSeparators('
      '$token)',
    );
  }

  @override
  void handleLiteralInt(Token token) {
    seen(token);
    doPrint(
      'handleLiteralInt('
      '$token)',
    );
  }

  @override
  void handleLiteralIntWithSeparators(Token token) {
    seen(token);
    doPrint(
      'handleLiteralIntWithSeparators('
      '$token)',
    );
  }

  @override
  void handleLiteralList(
    int count,
    Token leftBracket,
    Token? constKeyword,
    Token rightBracket,
  ) {
    seen(leftBracket);
    seen(constKeyword);
    seen(rightBracket);
    doPrint(
      'handleLiteralList('
      '$count, '
      '$leftBracket, '
      '$constKeyword, '
      '$rightBracket)',
    );
  }

  @override
  void handleListPattern(int count, Token leftBracket, Token rightBracket) {
    seen(leftBracket);
    seen(rightBracket);
    doPrint(
      'handleListPattern('
      '$count, '
      '$leftBracket, '
      '$rightBracket)',
    );
  }

  @override
  void handleLiteralSetOrMap(
    int count,
    Token leftBrace,
    Token? constKeyword,
    Token rightBrace,
    bool hasSetEntry,
  ) {
    seen(leftBrace);
    seen(constKeyword);
    seen(rightBrace);
    doPrint(
      'handleLiteralSetOrMap('
      '$count, '
      '$leftBrace, '
      '$constKeyword, '
      '$rightBrace, '
      '$hasSetEntry)',
    );
  }

  @override
  void handleMapPattern(int count, Token leftBrace, Token rightBrace) {
    seen(leftBrace);
    seen(rightBrace);
    doPrint(
      'handleMapPattern('
      '$count, '
      '$leftBrace, '
      '$rightBrace)',
    );
  }

  @override
  void handleLiteralNull(Token token) {
    seen(token);
    doPrint(
      'handleLiteralNull('
      '$token)',
    );
  }

  @override
  void handleNativeClause(Token nativeToken, bool hasName) {
    seen(nativeToken);
    doPrint(
      'handleNativeClause('
      '$nativeToken, '
      '$hasName)',
    );
  }

  @override
  void handleNamedArgument(Token colon) {
    seen(colon);
    doPrint(
      'handleNamedArgument('
      '$colon)',
    );
  }

  @override
  void handlePatternField(Token? colon) {
    seen(colon);
    doPrint(
      'handlePatternField('
      '$colon)',
    );
  }

  @override
  void handleNamedRecordField(Token colon) {
    seen(colon);
    doPrint(
      'handleNamedRecordField('
      '$colon)',
    );
  }

  @override
  void beginNewExpression(Token token) {
    seen(token);
    doPrint(
      'beginNewExpression('
      '$token)',
    );
    indent++;
  }

  @override
  void endNewExpression(Token token) {
    indent--;
    seen(token);
    doPrint(
      'endNewExpression('
      '$token)',
    );
  }

  @override
  void handleNoArguments(Token token) {
    seen(token);
    doPrint(
      'handleNoArguments('
      '$token)',
    );
  }

  @override
  void handleNoConstructorReferenceContinuationAfterTypeArguments(Token token) {
    seen(token);
    doPrint(
      'handleNoConstructorReferenceContinuationAfterTypeArguments('
      '$token)',
    );
  }

  @override
  void handleNoIdentifier(Token token, IdentifierContext identifierContext) {
    seen(token);
    doPrint(
      'handleNoIdentifier('
      '$token, '
      '$identifierContext)',
    );
  }

  @override
  void handleNoTypeNameInConstructorReference(Token token) {
    seen(token);
    doPrint(
      'handleNoTypeNameInConstructorReference('
      '$token)',
    );
  }

  @override
  void handleNoType(Token lastConsumed) {
    seen(lastConsumed);
    doPrint(
      'handleNoType('
      '$lastConsumed)',
    );
  }

  @override
  void handleNoTypeVariables(Token token) {
    seen(token);
    doPrint(
      'handleNoTypeVariables('
      '$token)',
    );
  }

  @override
  void handleOperator(Token token) {
    seen(token);
    doPrint(
      'handleOperator('
      '$token)',
    );
  }

  @override
  void handleSwitchCaseNoWhenClause(Token token) {
    seen(token);
    doPrint(
      'handleSwitchCaseNoWhenClause('
      '$token)',
    );
  }

  @override
  void handleSwitchExpressionCasePattern(Token token) {
    seen(token);
    doPrint(
      'handleSwitchExpressionCasePattern('
      '$token)',
    );
  }

  @override
  void handleSymbolVoid(Token token) {
    seen(token);
    doPrint(
      'handleSymbolVoid('
      '$token)',
    );
  }

  @override
  void handleOperatorName(Token operatorKeyword, Token token) {
    seen(operatorKeyword);
    seen(token);
    doPrint(
      'handleOperatorName('
      '$operatorKeyword, '
      '$token)',
    );
  }

  @override
  void handleInvalidOperatorName(Token operatorKeyword, Token token) {
    seen(operatorKeyword);
    seen(token);
    doPrint(
      'handleInvalidOperatorName('
      '$operatorKeyword, '
      '$token)',
    );
  }

  @override
  void handleParenthesizedCondition(Token token, Token? case_, Token? when) {
    seen(token);
    seen(case_);
    seen(when);
    doPrint(
      'handleParenthesizedCondition('
      '$token, '
      '$case_, '
      '$when)',
    );
  }

  @override
  void beginPattern(Token token) {
    seen(token);
    doPrint(
      'beginPattern('
      '$token)',
    );
    indent++;
  }

  @override
  void beginPatternGuard(Token when) {
    seen(when);
    doPrint(
      'beginPatternGuard('
      '$when)',
    );
    indent++;
  }

  @override
  void beginParenthesizedExpressionOrRecordLiteral(Token token) {
    seen(token);
    doPrint(
      'beginParenthesizedExpressionOrRecordLiteral('
      '$token)',
    );
    indent++;
  }

  @override
  void beginSwitchCaseWhenClause(Token when) {
    seen(when);
    doPrint(
      'beginSwitchCaseWhenClause('
      '$when)',
    );
    indent++;
  }

  @override
  void endRecordLiteral(Token token, int count, Token? constKeyword) {
    indent--;
    seen(token);
    seen(constKeyword);
    doPrint(
      'endRecordLiteral('
      '$token, '
      '$count, '
      '$constKeyword)',
    );
  }

  @override
  void handleRecordPattern(Token token, int count) {
    seen(token);
    doPrint(
      'handleRecordPattern('
      '$token, '
      '$count)',
    );
  }

  @override
  void endPattern(Token token) {
    indent--;
    seen(token);
    doPrint(
      'endPattern('
      '$token)',
    );
  }

  @override
  void endPatternGuard(Token token) {
    indent--;
    seen(token);
    doPrint(
      'endPatternGuard('
      '$token)',
    );
  }

  @override
  void endParenthesizedExpression(Token token) {
    indent--;
    seen(token);
    doPrint(
      'endParenthesizedExpression('
      '$token)',
    );
  }

  @override
  void endSwitchCaseWhenClause(Token token) {
    indent--;
    seen(token);
    doPrint(
      'endSwitchCaseWhenClause('
      '$token)',
    );
  }

  @override
  void handleParenthesizedPattern(Token token) {
    seen(token);
    doPrint(
      'handleParenthesizedPattern('
      '$token)',
    );
  }

  @override
  void beginConstantPattern(Token? constKeyword) {
    seen(constKeyword);
    doPrint(
      'beginConstantPattern('
      '$constKeyword)',
    );
    indent++;
  }

  @override
  void endConstantPattern(Token? constKeyword) {
    indent--;
    seen(constKeyword);
    doPrint(
      'endConstantPattern('
      '$constKeyword)',
    );
  }

  @override
  void handleObjectPattern(
    Token firstIdentifier,
    Token? dot,
    Token? secondIdentifier,
  ) {
    seen(firstIdentifier);
    seen(dot);
    seen(secondIdentifier);
    doPrint(
      'handleObjectPattern('
      '$firstIdentifier, '
      '$dot, '
      '$secondIdentifier)',
    );
  }

  @override
  void handleQualified(Token period) {
    seen(period);
    doPrint(
      'handleQualified('
      '$period)',
    );
  }

  @override
  void handleStringPart(Token token) {
    seen(token);
    doPrint(
      'handleStringPart('
      '$token)',
    );
  }

  @override
  void handleSuperExpression(Token token, IdentifierContext context) {
    seen(token);
    doPrint(
      'handleSuperExpression('
      '$token, '
      '$context)',
    );
  }

  @override
  void handleAugmentSuperExpression(
    Token augmentToken,
    Token superToken,
    IdentifierContext context,
  ) {
    seen(augmentToken);
    seen(superToken);
    doPrint(
      'handleAugmentSuperExpression('
      '$augmentToken, '
      '$superToken, '
      '$context)',
    );
  }

  @override
  void beginSwitchCase(int labelCount, int expressionCount, Token beginToken) {
    seen(beginToken);
    doPrint(
      'beginSwitchCase('
      '$labelCount, '
      '$expressionCount, '
      '$beginToken)',
    );
    indent++;
  }

  @override
  void endSwitchCase(
    int labelCount,
    int expressionCount,
    Token? defaultKeyword,
    Token? colonAfterDefault,
    int statementCount,
    Token beginToken,
    Token endToken,
  ) {
    indent--;
    seen(defaultKeyword);
    seen(colonAfterDefault);
    seen(beginToken);
    seen(endToken);
    doPrint(
      'endSwitchCase('
      '$labelCount, '
      '$expressionCount, '
      '$defaultKeyword, '
      '$colonAfterDefault, '
      '$statementCount, '
      '$beginToken, '
      '$endToken)',
    );
  }

  @override
  void beginSwitchExpressionCase() {
    doPrint('beginSwitchExpressionCase()');
    indent++;
  }

  @override
  void endSwitchExpressionCase(
    Token beginToken,
    Token? when,
    Token arrow,
    Token endToken,
  ) {
    indent--;
    seen(beginToken);
    seen(when);
    seen(arrow);
    seen(endToken);
    doPrint(
      'endSwitchExpressionCase('
      '$beginToken, '
      '$when, '
      '$arrow, '
      '$endToken)',
    );
  }

  @override
  void handleThisExpression(Token token, IdentifierContext context) {
    seen(token);
    doPrint(
      'handleThisExpression('
      '$token, '
      '$context)',
    );
  }

  @override
  void handleUnaryPostfixAssignmentExpression(Token token) {
    seen(token);
    doPrint(
      'handleUnaryPostfixAssignmentExpression('
      '$token)',
    );
  }

  @override
  void handleUnaryPrefixExpression(Token token) {
    seen(token);
    doPrint(
      'handleUnaryPrefixExpression('
      '$token)',
    );
  }

  @override
  void handleRelationalPattern(Token token) {
    seen(token);
    doPrint(
      'handleRelationalPattern('
      '$token)',
    );
  }

  @override
  void handleUnaryPrefixAssignmentExpression(Token token) {
    seen(token);
    doPrint(
      'handleUnaryPrefixAssignmentExpression('
      '$token)',
    );
  }

  @override
  void beginFormalParameterDefaultValueExpression() {
    doPrint('beginFormalParameterDefaultValueExpression()');
    indent++;
  }

  @override
  void endFormalParameterDefaultValueExpression() {
    indent--;
    doPrint('endFormalParameterDefaultValueExpression()');
  }

  @override
  void handleValuedFormalParameter(
    Token equals,
    Token token,
    FormalParameterKind kind,
  ) {
    seen(equals);
    seen(token);
    doPrint(
      'handleValuedFormalParameter('
      '$equals, '
      '$token, '
      '$kind)',
    );
  }

  @override
  void handleFormalParameterWithoutValue(Token token) {
    seen(token);
    doPrint(
      'handleFormalParameterWithoutValue('
      '$token)',
    );
  }

  @override
  void handleVoidKeyword(Token token) {
    seen(token);
    doPrint(
      'handleVoidKeyword('
      '$token)',
    );
  }

  @override
  void handleVoidKeywordWithTypeArguments(Token token) {
    seen(token);
    doPrint(
      'handleVoidKeywordWithTypeArguments('
      '$token)',
    );
  }

  @override
  void beginYieldStatement(Token token) {
    seen(token);
    doPrint(
      'beginYieldStatement('
      '$token)',
    );
    indent++;
  }

  @override
  void endYieldStatement(Token yieldToken, Token? starToken, Token endToken) {
    indent--;
    seen(yieldToken);
    seen(starToken);
    seen(endToken);
    doPrint(
      'endYieldStatement('
      '$yieldToken, '
      '$starToken, '
      '$endToken)',
    );
  }

  @override
  void endInvalidYieldStatement(
    Token beginToken,
    Token? starToken,
    Token endToken,
    MessageCode errorCode,
  ) {
    indent--;
    seen(beginToken);
    seen(starToken);
    seen(endToken);
    doPrint(
      'endInvalidYieldStatement('
      '$beginToken, '
      '$starToken, '
      '$endToken, '
      '$errorCode)',
    );
  }

  @override
  void handleRecoverableError(
    Message message,
    Token startToken,
    Token endToken,
  ) {
    seen(startToken);
    seen(endToken);
    doPrint(
      'handleRecoverableError('
      '$message, '
      '$startToken, '
      '$endToken)',
    );
    checkEof(endToken);
  }

  @override
  void handleExperimentNotEnabled(
    ExperimentalFlag experimentalFlag,
    Token beginToken,
    Token endToken,
  ) {
    seen(beginToken);
    seen(endToken);
    doPrint(
      'handleExperimentNotEnabled('
      '$experimentalFlag, '
      '$beginToken, '
      '$endToken)',
    );
  }

  @override
  void handleErrorToken(ErrorToken token) {
    doPrint(
      'handleErrorToken('
      '$token)',
    );
    handleRecoverableError(token.assertionMessage, token, token);
  }

  @override
  void handleUnescapeError(
    Message message,
    Token location,
    int stringOffset,
    int length,
  ) {
    seen(location);
    doPrint(
      'handleUnescapeError('
      '$message, '
      '$location, '
      '$stringOffset, '
      '$length)',
    );
  }

  @override
  void handleInvalidStatement(Token token, Message message) {
    seen(token);
    doPrint(
      'handleInvalidStatement('
      '$token, '
      '$message)',
    );
  }

  @override
  void handleScript(Token token) {
    seen(token);
    doPrint(
      'handleScript('
      '$token)',
    );
  }

  @override
  void handleTypeArgumentApplication(Token openAngleBracket) {
    seen(openAngleBracket);
    doPrint(
      'handleTypeArgumentApplication('
      '$openAngleBracket)',
    );
  }

  @override
  void handleNewAsIdentifier(Token token) {
    seen(token);
    doPrint(
      'handleNewAsIdentifier('
      '$token)',
    );
  }

  @override
  void handlePatternVariableDeclarationStatement(
    Token keyword,
    Token equals,
    Token semicolon,
  ) {
    seen(keyword);
    seen(equals);
    seen(semicolon);
    doPrint(
      'handlePatternVariableDeclarationStatement('
      '$keyword, '
      '$equals, '
      '$semicolon)',
    );
  }

  @override
  void handlePatternAssignment(Token equals) {
    seen(equals);
    doPrint(
      'handlePatternAssignment('
      '$equals)',
    );
  }

  @override
  void handleDotShorthandContext(Token token) {
    seen(token);
    doPrint(
      'handleDotShorthandContext('
      '$token)',
    );
  }

  @override
  void handleDotShorthandHead(Token token) {
    seen(token);
    doPrint(
      'handleDotShorthandHead('
      '$token)',
    );
  }

  @override
  void beginConstDotShorthand(Token token) {
    seen(token);
    doPrint(
      'beginConstDotShorthand('
      '$token)',
    );
    indent++;
  }

  @override
  void endConstDotShorthand(Token token) {
    indent--;
    seen(token);
    doPrint(
      'endConstDotShorthand('
      '$token)',
    );
  }
}
